package com.kaiwukj.android.ufamily.app.base.review;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.blankj.utilcode.util.BarUtils;
import com.blankj.utilcode.util.LogUtils;
import com.kaiwukj.android.mcas.base.BaseApplication;
import com.kaiwukj.android.mcas.base.delegate.IFragment;
import com.kaiwukj.android.mcas.di.component.AppComponent;
import com.kaiwukj.android.mcas.integration.cache.Cache;
import com.kaiwukj.android.mcas.integration.cache.CacheType;
import com.kaiwukj.android.mcas.integration.lifecycle.FragmentLifecycleable;
import com.kaiwukj.android.mcas.utils.McaUtils;
import com.kaiwukj.android.mcas.utils.UToast;
import com.kaiwukj.android.ufamily.R;
import com.kaiwukj.android.ufamily.app.MyApplication;
import com.kaiwukj.android.ufamily.mvp.ui.widget.DefaultDialog;
import com.kaiwukj.android.ufamily.mvp.ui.widget.OkClickListener;
import com.trello.rxlifecycle2.android.FragmentEvent;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import butterknife.ButterKnife;
import butterknife.Unbinder;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.subjects.BehaviorSubject;
import io.reactivex.subjects.Subject;
import me.yokeyword.fragmentation.SupportFragment;

public abstract class BaseFragment extends SupportFragment
        implements IFragment, FragmentLifecycleable {

    private View mView;

    private Unbinder unbinder;

    protected boolean isInited = true;

    private Cache<String, Object> mCache;

    private boolean isFirst = true;

    protected Context mContext;

    private final BehaviorSubject<FragmentEvent> mLifecycleSubject = BehaviorSubject.create();


    protected abstract int getLayoutId();

    protected abstract void initView();

    protected abstract void initData(Bundle savedInstanceState);

    /**
     * ViewPager使用该方法初始化数据(ViewPager2可以使用上面的抽象方法{@link BaseFragment@initData(savedInstanceState)})
     */
    protected void initDataSupport() {
    }

    private CompositeDisposable mCompositeDisposable;

    protected void subscribe(Disposable disposable) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(disposable);
    }

    protected void unSubscribe() {
        if (mCompositeDisposable != null && !mCompositeDisposable.isDisposed()) {
            mCompositeDisposable.dispose();
        }
    }

    @SuppressWarnings("unchecked")
    @NonNull
    @Override
    public Cache<String, Object> provideCache() {
        if (mCache == null) {
            mCache = McaUtils.obtainAppComponentFromContext(getActivity()).cacheFactory().build(CacheType.FRAGMENT_CACHE);
        }
        return mCache;
    }

    protected void setPaddingTop(@IdRes int viewId, int top) {
        try {
            View view = mView.findViewById(viewId);
            //ViewGroup.LayoutParams params = view.getLayoutParams();
            //params.height = view.getHeight() + top;
            //view.setLayoutParams(params);
            if (view == null) return;
            view.setPadding(view.getPaddingStart(), top + view.getPaddingTop(), view.getPaddingEnd(), view.getPaddingBottom());
        } catch (Resources.NotFoundException e) {
            LogUtils.e("view_root not found:" + e.getLocalizedMessage());
        }
    }

    /**
     * 需要测量View(onResume()之后)
     *
     * @param viewId
     */
    protected void setPaddingTop(@IdRes int viewId) {
        int top = BarUtils.getStatusBarHeight();
        try {
            View view = mView.findViewById(viewId);
            if (view == null) return;
            ViewGroup.LayoutParams params = view.getLayoutParams();
            params.height = view.getHeight() + top;
            view.setLayoutParams(params);
            view.setPadding(view.getPaddingStart(), top + view.getPaddingTop(), view.getPaddingEnd(), view.getPaddingBottom());
        } catch (Resources.NotFoundException e) {
            LogUtils.e("view_root not found:" + e.getLocalizedMessage());
        }
    }

    @NonNull
    @Override
    public Subject<FragmentEvent> provideLifecycleSubject() {
        return mLifecycleSubject;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (mView == null) {
            mView = inflater.inflate(getLayoutId(), container, false);
        }/* else {
            ViewGroup viewGroup = (ViewGroup) mView.getParent();
            if (viewGroup != null) {
                viewGroup.removeView(mView);
            }
        }*/
        return mView;
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        mContext = context;
    }

    @Override
    public void onResume() {
        super.onResume();
        //LogUtils.d("----------onResume---------");
        if (isFirst) {
            isFirst = false;
            initDataSupport();
        }
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //  LogUtils.d("----------onViewCreated---------");
        if (unbinder == null) {
            unbinder = ButterKnife.bind(this, mView);
            setPaddingTop(R.id.root_view, BarUtils.getStatusBarHeight());
            initView();
        }
    }

    @Override
    public void onSupportVisible() {
        super.onSupportVisible();
        //  LogUtils.d("----------onSupportVisible---------");
    }

    @Override
    public void onLazyInitView(@Nullable Bundle savedInstanceState) {
        super.onLazyInitView(savedInstanceState);
        // LogUtils.d("----------onLazyInitView---------");
        if (isInited) {
            isInited = false;
            // initView();
            if (useEventBus() && !EventBus.getDefault().isRegistered(this)) {
                EventBus.getDefault().register(this);
            }
            initData(savedInstanceState);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(Object event) {
    }

    @Override
    public void setupFragmentComponent(@NonNull AppComponent appComponent) {

    }

    @Override
    public boolean useEventBus() {
        return true;
    }

    @Override
    public void onDetach() {
        hideLoading();
        super.onDetach();
        if (useEventBus() && EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        unSubscribe();
        try {
            if (unbinder != null) {
                unbinder.unbind();
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }

    protected MyApplication getApp() {
        return MyApplication.getInstance();
    }

    protected AppComponent getAppComponent() {
        return BaseApplication.getInstance().getAppComponent();
    }

    protected void showMessage(String msg) {
        if (!TextUtils.isEmpty(msg)) {
            UToast.showShort(getContext(), msg);
        }
    }

    protected void showLoading(String loadingMsg) {
        if (isAdded() && getActivity() != null && getActivity() instanceof BaseActivity) {
            ((BaseActivity) getActivity()).showLoading(loadingMsg);
        }
    }

    protected void hideLoading() {
        if (getActivity() != null && getActivity() instanceof BaseActivity) {
            ((BaseActivity) getActivity()).hideLoading();
        }
    }

    /**
     * 显示一个true or false dialog
     *
     * @param context    context
     * @param message    message
     * @param okListener {@link OkClickListener}
     */
    protected static void showMessageOKCancel(final Activity context,
                                              String message,
                                              OkClickListener okListener) {
        DefaultDialog defaultDialog = new DefaultDialog(context);
        defaultDialog.setContent(message);
        defaultDialog.setOkClickListener(okListener);
        defaultDialog.show();
    }

}
